package com.jy.rhin.valid;


import com.jy.rhin.infra.cda.DataElement;
import com.jy.rhin.infra.cda.EDataElement;
import com.jy.rhin.infra.cda.XValid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.regex.Pattern;

/**
 * @Author 姚俊
 * @Date 2023/2/24 11:15
 * @Description 数据元验证器
 */
@Component
@Slf4j
public class DataElementValid extends AbsValid {
    @Resource
    NullableValid nullableValid;
    @Resource
    DT15Valid dt15Valid;

    @Resource
    TFValid tfValid;

    /**
     * @Description 先判断值是否可为空 在判断是否符合数据元格式
     */
    @Override
    public String validate(XValid xValid, String value) {
        String validateMsg = nullableValid.validate(xValid, value);
        if (!StringUtils.isEmpty(validateMsg)) {
            return validateMsg;
        } else {
            EDataElement eDataElement = xValid.dataElement();
            if (EDataElement.NONE.equals(eDataElement)) {
                log.error("未枚举数据元:{}", eDataElement);
                return "数据元获取错误";
            } else {
                DataElement dataElement = eDataElement.getDataElement();
                String format = dataElement.getFormat();
                if (format.startsWith("AN")) {
                    String f = format.replace("AN", "");
                    String regExAN = getRegExAN(f);
                    return patternValid(format, regExAN, value);
                } else if (format.startsWith("A")) {
                    String f = format.replace("A", "");
                    String regExAN = getRegExA(f);
                    return patternValid(format, regExAN, value);
                } else if (format.startsWith("N")) {
                    String f = format.replace("N", "");
                    String regExAN = getRegExNum(f);
                    return patternValid(format, regExAN, value);
                } else if (format.equals("T/F")) {
                    return tfValid.validate(xValid, value);
                } else if (format.equals("DT15") || format.equals("D8")) {
                    return dt15Valid.validate(xValid, value);
                } else {
                    log.warn("未配置表达式验证:{}", format);
                }
            }
        }
        return null;
    }

    String patternValid(String format, String regEx, String value) {
        if (Pattern.matches(regEx, value)) {
            return null;
        } else {
            return "不符合格式-" + format;
        }
    }

    /**
     * @Description 获取数字正则
     */
    public static String getRegExNum(String format) {
        if (format.contains("..") && format.contains(",")) {  //N..8,2 //N3..5,2
            String reg = "^(\\-|\\+)?\\d{$num1,$num2}(\\.[0-9]{$num3})$";
            String num1 = "1";
            String[] split = format.split("\\..");
            String[] split1 = split[1].split(",");
            int num2 = Integer.parseInt(split1[0]);
            int num3 = Integer.parseInt(split1[1]);
            if (StringUtils.isNoneEmpty(split[0])) {
                num1 = Integer.parseInt(split[0]) - 1 - num3 + "";
            }
            return reg.replace("$num1", num1).replace("$num2", num2 - num3 - 1 + "").replace("$num3", num3 + "");

        } else if (format.contains("..")) {  //最大值
            String reg = "^(\\-|\\+)?\\d{$num1,$num2}$";
            String[] split = format.split("\\..");
            return reg.replace("$num1", StringUtils.isEmpty(split[0])? "1":split[0]).replace("$num2", split[1]);
        } else if (format.contains(",")) { //精度 整数部分num1-num2-1 8,2
            String reg = "^(\\-|\\+)?[0-9]{$num1}+(\\.[0-9]{$num2})?$";
            String[] split = format.split(",");
            int num1 = Integer.parseInt(split[0]);
            int num2 = Integer.parseInt(split[1]);
            return reg.replace("$num1", num1 - num2 - 1 + "").replace("$num2", num2 + "");
        } else {  //定长
            String reg = "^(\\-|\\+)?\\d{$length}$";
            return reg.replace("$length", format);
        }
    }

    /**
     * @Description 中英文数字正则
     */
    public static String getRegExAN(String format) {
//        String reg = "^[A-Za-z0-9-\\u4e00-\\u9fa5]{$exp}$";
        String reg = "^.{$exp}$";
        String exp;
        String[] ans = format.split("\\..");
        if (ans.length == 1) {
            exp = ans[0];
        } else {
            if (StringUtils.isEmpty(ans[0])) {
                exp = "0" + "," + ans[1];
            } else {
                exp = ans[0] + "," + ans[1];
            }
        }
        return reg.replace("$exp", exp);
    }

    /**
     * @Description 英文字符
     */
    String getRegExA(String format) {
        String reg = "^.{$exp}$";
        //String reg = "^[A-Za-z\\u4e00-\\u9fa5]{$exp}$";
        String exp;
        String[] ans = format.split("\\..");
        if (ans.length == 1) {
            exp = ans[0];
        } else {
            if (StringUtils.isEmpty(ans[0])) {
                exp = "0" + "," + ans[1];
            } else {
                exp = ans[0] + "," + ans[1];
            }
        }
        return reg.replace("$exp", exp);
    }
}
